home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 28
/
Aminet 28 (1998)(GTI - Schatztruhe)[!][Dec 1998].iso
/
Aminet
/
game
/
board
/
Exchess.lha
/
EXChess
/
main.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
1998-08-22
|
31KB
|
928 lines
/* Main functions controlling program */
#include <iostream.h>
#include <iomanip.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <stdio.h>
#include <signal.h>
#include <fstream.h>
#include "define.h"
#if UNIX
#include <sys/types.h>
#include <sys/time.h>
#else
#include <time.h>
#include <windows.h>
#undef BLACK
#undef WHITE
#include <conio.h>
#define BLACK 0
#define WHITE 1
#endif
// Custom headers, defining external functions and struct types for
// board, piece and moves. And defining global variables.
#include "chess.h"
#include "const.h"
#include "funct.h"
#include "main.h"
#include "hash.h"
// moves to time control, base time, increment, time left;
int omttc = 0, mttc = 0, inc = 0; float base = 30, timeleft = 30;
int display_board = 0;
int analysis_mode = 0;
extern int fail; // flag for fail high/fail low from search
extern move ponder_move;
// xboard flag
int xboard, post, ics, ALLEG = 0, hintflag = 0, count = 1;
int ponder_flag = 1, learn_bk, shout_book;
extern int ponder, last_ponder, learn_count, learned, TAB_SIZE, PAWN_SIZE;
// executable directory
char exec_path[100];
#if UNIX
fd_set read_fds;
struct timeval timeout = { 0, 0 };
#endif
/*------------------------- Main Function ---------------------------*/
// Main control function that interacts with the User
int main(int argc, char *argv[])
{
char mstring[10];
move hint;
xboard = 0; ponder = 0; ics = 0;
learn_count = 0; learned = 0; learn_bk = 1; shout_book = 0;
strcpy(exec_path, argv[0]);
// parsing exec path
int last_slash = 0;
for(int j = 0; j < 100; j++) {
if(exec_path[j] == '\0') break;
if(exec_path[j] == '\\') last_slash = j;
if(exec_path[j] == '/') last_slash = j;
}
exec_path[last_slash+1] = '\0';
open_hash(); gen_check_table(); set_score_param();
if(argc > 1) {
if(!strcmp(argv[1], "xb")) xboard = 1;
if(!strcmp(argv[1], "hash")) set_hash_size(atoi(argv[2]));
if(argc > 2)
if(!strcmp(argv[2], "hash")) set_hash_size(atoi(argv[3]));
}
if(!xboard) {
cout << "\nExperimental Chess Program (EXchess) version " << VERS << ","
<< "\nCopyright (C) 1997-98 Daniel C. Homan, Waltham MA, USA"
<< "\nEXchess comes with ABSOLUTELY NO WARRANTY. This is free"
<< "\nsoftware, and you are welcome to redistribute it under"
<< "\ncertain conditions. This program is distributed under the"
<< "\nGNU public license. See the files license.txt and readme.txt"
<< "\nfor more information.\n\n";
cout << "Hash size = " << TAB_SIZE << " entries, "
<< TAB_SIZE*sizeof(hash_rec) << " bytes\n";
cout << "Pawn size = " << PAWN_SIZE << " entries, "
<< PAWN_SIZE*sizeof(pawn_rec) << " bytes\n\n";
cout << "Type 'help' for a list of commands.\n";
}
setboard(i_pos, 'w', 1); // set up the board
while (count > 0)
{
// find a hint move, check book first then look in pv
if(hintflag) {
hint.t = 0;
if(last_ponder) hint = ponder_move;
else if(book) hint = opening_book(game_pos.hcode, &game_pos);
if(!hint.t) hint = pc[0][1];
if(hint.t) {
print_move(game_pos, hint, mstring);
cout << "Hint: " << mstring << "\n";
}
hintflag = 0;
}
signal(SIGINT, SIG_IGN);
// pondering if possible
if(T > 2 && p_side == game_pos.wtm
&& !both && !last_ponder && ponder_flag)
{
if(!xboard) cout << "pondering... (press any key to interrupt)\n";
cout.flush();
ponder = 1;
search(game_pos, 10000, T+1);
ponder = 0;
last_ponder = 1;
}
// if analysis_mode, do some analysis
if(analysis_mode) {
search(game_pos, 360000, T);
}
if(!game_pos.wtm) // if it is black's turn
{
if(both) p_side = 0;
if(!xboard) cout << "Black-To-Move[" << ceil(T/2) << "]: ";
}
else // or if it is white's
{
if(both) p_side = 1;
if(!xboard) cout << "White-To-Move[" << (ceil(T/2) + 1) << "]: ";
}
cout.flush();
legalmoves(&game_pos, &movelist); // find legal moves
if(p_side == game_pos.wtm || game_over) {
cin >> response; // get the command
if((last_ponder || analysis_mode) && UNIX) cout << "\n";
parse_command(); // parse it
} else {
if(!xboard) cout << "Thinking ...\n";
cout.flush();
make_move();
last_ponder = 0;
T++;
}
cout.flush();
}
close_hash();
return 0;
}
// Function to takeback moves
// tm is the number of moves to take back.
// 1 or 2 with current setup
void takeback(int tm)
{
int temp_turn = T;
setboard(i_pos, 'w', 1);
T = temp_turn; if(!(T % 2)) p_side = 0;
if(p_side == 0 && tm == 1) p_side = 1;
for (int ip = 0; ip <= T-2-tm; ip++)
{
exec_move(&game_pos, game_history[ip], 0);
}
if(!xboard) drawboard();
T = T - tm;
}
// Function to make the next move... If it is the computer's turn, this
// function calls the search algorithm, takes the best move given by that
// search, and makes the move - unless it is a check move: then it flagges
// stale-mate.....
// The function also looks to see if this move places the opponent in check
// or check-mate.
void make_move()
{
time_t mtime = time(NULL); int time_limit, legal;
char mstring[10];
// If it is not the player's turn, figure out how much time to use,
// execute the search algorithm to start the search process and return
// the best move.
if(mttc && mttc < 25)
{ time_limit = int(timeleft/(mttc+1)) + inc; }
else if (mttc >= 25 || xboard) { time_limit = int(timeleft/25) + inc; }
else { time_limit = int(timeleft); }
if (p_side != game_pos.wtm)
{
best = search(game_pos, time_limit, T);
timeleft -= time(NULL) - mtime; timeleft += inc;
if(mttc) { mttc--; if(!mttc) { timeleft += base; mttc = omttc; } }
if(mttc <= 0 && !xboard) { timeleft = base; mttc = omttc; }
}
// execute the move....
temp_pos = game_pos;
legal = exec_move(&temp_pos, best, 0);
// Is the move legal? if not Error ....
if (legal)
{
// if it is the computer's turn - echo the move
if(p_side != game_pos.wtm)
{
if(game_pos.wtm) {
cout << (ceil(T/2) + 1) << ". "; if(xboard) cout << "... ";
}
else { cout << ceil(T/2) << ". ... "; }
print_move(game_pos, best, mstring);
cout << mstring;
cout << "\n";
}
last_pos = game_pos; // Save last position
game_pos = temp_pos; // actually execute move
// Check if we have, check_mate, stale_mate, or a continuing game...
switch (check_mate(&game_pos))
{
case 0:
if(game_pos.fifty >= 100)
{ cout << "1/2-1/2 {50 moves}\n";
if(ics) cout << "tellics draw\n"; }
else if(check(&game_pos, game_pos.wtm) && !xboard)
{ cout << "Check!\n"; }
break;
case 1:
game_over = 1;
if(!game_pos.wtm) cout << "1-0 {White Mates}\n";
else cout << "0-1 {Black Mates}\n";
break;
case 2:
game_over = 1;
cout << "1/2-1/2 {Stalemate}\n";
}
game_history[T-1] = best; // record the move in the history list
p_list[T-1] = game_pos.hcode;
if(!xboard && display_board) drawboard(); // draw the resulting board
}
else { game_over = 1; cout << "Error - please reset"; }
}
// This function sets up the board from EPD format
void setboard(char inboard[60], char ms, int castle)
{
int rx = 0, ry = 7, i; // control variables
// no book learning yet
learn_count = 0; learned = 0;
// game is not over
game_over = 0;
// initializing castling status if necessary
if (castle) { game_pos.castle = 15; } else { game_pos.castle = 0; }
// Side to move
if (ms == 'b')